package com.xqboss.apps.controller.nft;

import com.xqboss.apps.domain.param.AesParams;
import com.xqboss.apps.dto.equipment.CalcBaseRepairsDurabilityDto;
import com.xqboss.apps.dto.equipment.CalcRepairsDurabilityUsedDto;
import com.xqboss.apps.dto.equipment.RepairsDurabilityDto;
import com.xqboss.apps.dto.nft.NftTransferDto;
import com.xqboss.apps.dto.user.AppUserNftListDto;
import com.xqboss.apps.dto.user.UserNftListDto;
import com.xqboss.apps.enums.nft.NftTypeEnum;
import com.xqboss.apps.enums.nft.UserNftStatusEnum;
import com.xqboss.apps.service.consumer.ConsumerRealNameService;
import com.xqboss.apps.service.equipment.EquipmentService;
import com.xqboss.apps.service.nft.NftTransferConfigService;
import com.xqboss.apps.service.punch.PunchUserConfigService;
import com.xqboss.apps.service.user.SysUserNftService;
import com.xqboss.apps.vo.equipment.RepairsDurabilityIntegralVo;
import com.xqboss.apps.vo.punch.UserPunchEquipmentVo;
import com.xqboss.apps.vo.user.AppUserNFTItemVo;
import com.xqboss.apps.vo.user.UserNFTItemVo;
import com.xqboss.apps.vo.user.UserNFTVo;
import com.xqboss.common.annotation.RepeatSubmit;
import com.xqboss.common.core.controller.BaseController;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.ValidatorUtil;
import com.xqboss.common.utils.aes.AesUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
 * @author Administrator
 */

@Api(tags = {"藏品、装备管理"})
@RestController
@RequestMapping("/apps/nft")
public class UserNftController extends BaseController {

    @Autowired
    private SysUserNftService userNftService;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private PunchUserConfigService punchUserConfigService;

    @Autowired
    private NftTransferConfigService nftTransferConfigService;

    @Autowired
    private ConsumerRealNameService consumerRealNameService;

    @ApiOperation("获取典藏列表（以编号为单位）-装备铺")
    @GetMapping("number-lists")
    public R<List<AppUserNFTItemVo>> numberList(@Validated AppUserNftListDto request) {
        request.setUserId(getUserId());
        List<AppUserNFTItemVo> voList = userNftService.getAppNftNumberList(request);
        return R.ok(voList);
    }

    @ApiOperation("获取典藏列表（以编号为单位）")
    @GetMapping("number-list")
    public R<List<UserNFTItemVo>> numberList(@Validated UserNftListDto request) {
        request.setUserId(getUserId());
        List<UserNFTItemVo> voList = userNftService.getNftNumberList(request);
        return R.ok(voList);
    }

    @ApiOperation("背包-装备列表")
    @GetMapping("knapsack-equipment-list")
    public R<List<UserPunchEquipmentVo>> knapsackEquipmentList() {
        Long userId = getUserId();
        List<UserPunchEquipmentVo> voList = userNftService.knapsackEquipmentList(userId);
        return R.ok(voList);
    }

    @ApiOperation("获取典藏列表（以典藏为单位）")
    @GetMapping("nft-list")
    public R<List<UserNFTVo>> nftList(@Validated UserNftListDto request) {
        request.startPage();
        request.setUserId(getUserId());
        List<UserNFTVo> voList = userNftService.getNftGroupList(request);
        return R.ok(voList);
    }

    @ApiOperation("获取典藏/装备详情")
    @PostMapping("detail/{userNftId}")
    public R<UserNFTItemVo> detail(@Validated @PathVariable("userNftId")
                                   @ApiParam(value = "用户典藏编号", required = true)
                                   @NotNull(message = "用户典藏编号不能为空")
                                   Long userNftId) {
        UserNFTItemVo vo = userNftService.getNftItemInfo(userNftId, getUserId());
        if(vo.getNftType() == NftTypeEnum.EQUIPMENT){
            // 如果是装备藏品，并且状态为使用中，判断是否在打卡中
            if(vo.getNftStatus() == UserNftStatusEnum.USED){
                vo.setIsPunchTime(punchUserConfigService.isPunchTime(getUserId()));
            }
        }
        return R.ok(vo);
    }


    @ApiOperation("计算装备修复耐久度耗费积分")
    @GetMapping("calc-repairs-durability")
    public R<RepairsDurabilityIntegralVo> calcRepairs(@Validated CalcRepairsDurabilityUsedDto dto) {
        RepairsDurabilityIntegralVo vo;
        if(Objects.isNull(dto.getTargetDurability())){
            // 最佳修复配置
            vo = equipmentService.getBestFixDurability(dto.getUserNftId(), getUserId());
        }else{
            // 指定修复配置
            vo = equipmentService.calcFixDurability(getUserId(), dto.getUserNftId(), dto.getTargetDurability());
        }
        return R.ok(vo);
    }


    @RepeatSubmit(interval = 500, justUrl = true)
    @ApiOperation("修复装备耐久度")
    @PostMapping("repairs-durability")
    public R repairs(@Validated @RequestBody RepairsDurabilityDto dto) {
        //如果扳手为空，或者热豆为空，设置为0
        if(Objects.isNull(dto.getWrench())){
            dto.setWrench(BigDecimal.ZERO);
        }
        if(Objects.isNull(dto.getIntegral())){
            dto.setIntegral(BigDecimal.ZERO);
        }
        //如果扳手小于0，或者热豆小于0，抛出异常;
        if (dto.getWrench().compareTo(BigDecimal.ZERO) < 0 || dto.getIntegral().compareTo(BigDecimal.ZERO) < 0) {
            throw new ServiceException("修复材料不足");
        }
        equipmentService.fixDurability(getUserId(), dto.getUserNftId(), dto.getIntegral(),  dto.getWrench(), dto.getTargetDurability());
        return R.ok();
    }

    @ApiOperation("获取装备最优修复参数")
    @GetMapping("base-repairs")
    public R<RepairsDurabilityIntegralVo> calcRepairs(@Validated CalcBaseRepairsDurabilityDto dto) {
        RepairsDurabilityIntegralVo vo = equipmentService.getBestFixDurability(dto.getUserNftId(), getUserId());
        return R.ok(vo);
    }


    @ApiOperation("获取用户背包所有（未使用）藏品装备编码")
    @GetMapping("all-nft-number-str/{nftId}")
    public R<List<String>> allNftNumberStr(@PathVariable("nftId")
                                           @ApiParam(value = "藏品id", required = true)
                                           @NotNull(message = "藏品id不能为空")
                                           Long nftId) {
        Long userId = getUserId();
        List<String> vo = userNftService.allNftNumberStr(userId, nftId);
        return R.ok(vo);
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @ApiOperation("藏品装备转赠")
    @PostMapping("transfer")
    public R transfer(@Validated @RequestBody AesParams param) {
        NftTransferDto params = AesUtil.decryptToObject(param.getParamStr(), NftTransferDto.class);
        ValidatorUtil.valid(params);
        Long userId = getUserId();
        // 校验赠送对象是否实名认证
        consumerRealNameService.requireRealName(userId);
        NftTransferDto dto = nftTransferConfigService.verifyTransfer(userId, params);
        userNftService.transfer(userId, dto);
        return R.ok();
    }
}
